from django_redis import get_redis_connection
from rest_framework import serializers


# 此序列化器的作用是 在用户绑定页面对相关参数进行序列化 参数的校验
from oauth.models import OAuthQQUser
from oauth.utils import check_encrypted_openid
from users.models import User


class QQuserSerializer(serializers.Serializer):
    ''' QQ登陆创建用户的序列化器'''

    # 1.定义序列化的相关字段
    openid = serializers.CharField(label='openid', write_only=True)
    mobile = serializers.RegexField(label='手机号', regex=r'^1[3-9]\d{9}$', write_only=True)
    password = serializers.CharField(label='密码', max_length=20, min_length=8, write_only=True)
    sms_code = serializers.CharField(label='短信验证码   ', write_only=True)

    # validate 是个校验方法 指定全部字段
    def validate(self, attrs):

        mobile = attrs['mobile']
        password = attrs['password']
        sms_code = attrs['sms_code']

        # 1. 校验短信验证码

        # （01） 创建redis的连接对象(取得游标)
        redis_conn = get_redis_connection('sms_codes')

        # （02） 用前端传过来的mobile 通过游标拿到redis中mobile对应的值（验证码）此验证码为bytes类型需要转
        real_sms_code = redis_conn.get('sms_%s'% mobile)

        # 判断验证码是否存在
        if not real_sms_code:
            raise serializers.ValidationError({'message': '短信验证码无效'})
        # 通过redis用用户输入的手机号查询验证码和前端输入的验证码进行比较
        if real_sms_code.decode() != sms_code:
            raise serializers.ValidationError({'message': '短信验证码错误'})

        # 根据手机号查询手机号对应的用户
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # 如果用户不存在， 则自动新增一个美多用户， 再进行绑定
            user = User.objects.create_user(
                username=mobile,
                password=password,
                mobile=mobile)
        else:
            # 如果绑定的用户存在，则校验密码是否正确
            if not user.check_password(password):
                raise serializers.ValidationError({'message': '用户密码不正确'})

        # 将认证后的user放进校验字典中， 绑定关联时间用到
        attrs['user'] = user

        # 获取openid， 检验openid是否有效 encrypted_openid加密的openid
        encrypted_openid = attrs['openid']

        openid = check_encrypted_openid(encrypted_openid)
        if not openid:
            raise serializers.ValidationError({'message': '无效的openid'})
        # 通过attrs拿到前端所有的值
        attrs['openid'] = openid

        return attrs

    # 重写create方法 新增一条数据
    def create(self, validated_data):

        # 获取校验的用户
        user = validated_data.get('user')
        openid = validated_data.get('openid')

        # 绑定openid和美多用户； 新增一条数据
        OAuthQQUser.objects.create(
            openid=openid,
            user=user)

        # 返回美多对象
        return user